
package org.apache.solr.search;

import java.net.URL;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.FieldCache.CacheEntry;
import org.apache.lucene.util.FieldCacheSanityChecker;
import org.apache.lucene.util.FieldCacheSanityChecker.Insanity;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoMBean;

/**
 * A SolrInfoMBean that provides introspection of the Lucene FiledCache, this is <b>NOT</b> a cache that is manged by Solr.
 */
public class SolrFieldCacheMBean implements SolrInfoMBean {

    protected FieldCacheSanityChecker checker = new FieldCacheSanityChecker();

    @Override
    public String getName() {
        return this.getClass().getName();
    }

    @Override
    public String getVersion() {
        return SolrCore.version;
    }

    @Override
    public String getDescription() {
        return "Provides introspection of the Lucene FieldCache, "
                + "this is **NOT** a cache that is managed by Solr.";
    }

    @Override
    public Category getCategory() {
        return Category.CACHE;
    }

    @Override
    public String getSource() {
        return "$URL: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene_solr_4_0/solr/core/src/java/org/apache/solr/search/SolrFieldCacheMBean.java $";
    }

    @Override
    public URL[] getDocs() {
        return null;
    }

    @Override
    public NamedList getStatistics() {

        NamedList stats = new SimpleOrderedMap();
        CacheEntry[] entries = FieldCache.DEFAULT.getCacheEntries();
        stats.add("entries_count", entries.length);
        for (int i = 0; i < entries.length; i++) {
            CacheEntry e = entries[i];
            stats.add("entry#" + i, e.toString());
        }

        Insanity[] insanity = checker.check(entries);

        stats.add("insanity_count", insanity.length);
        for (int i = 0; i < insanity.length; i++) {

            /**
             * RAM estimation is both CPU and memory intensive... we don't want
             * to do it unless asked. // we only estimate the size of insane
             * entries for (CacheEntry e : insanity[i].getCacheEntries()) { //
             * don't re-estimate if we've already done it. if (null ==
             * e.getEstimatedSize()) e.estimateSize(); }
             */
            stats.add("insanity#" + i, insanity[i].toString());
        }
        return stats;
    }
}
